home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- * flsun.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
- *
- * Copyright (C) 1989,1990 by Michael Mauldin. Permission is granted
- * to use this file in whole or in part for any purpose, educational,
- * recreational or commercial, provided that this copyright notice
- * is retained unchanged. This software is available to all free of
- * charge by anonymous FTP and in the UUNET archives.
- *
- * flsun.c:
- *
- * CONTENTS
- * read_sun (image, rfile, mstr, mlen)
- * write_sun (image, wfile)
- *
- * EDITLOG
- * LastEditDate = Mon Jun 25 00:18:04 1990 - Michael Mauldin
- * LastFileName = /usr2/mlm/src/misc/fbm/flsun.c
- *
- * HISTORY
- * 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
- * Package for Release 1.0
- *
- * 20-May-89 Michael Mauldin (mlm) at Carnegie Mellon University
- * Fixed problem with odd length rows on reading
- *
- * 26-Aug-89 Michael Mauldin (mlm) at Carnegie Mellon University
- * Beta release (version 0.96) mlm@cs.cmu.edu
- *
- * 12-Nov-88 Michael Mauldin (mlm) at Carnegie-Mellon University
- * Created.
- *****************************************************************/
-
- # include <stdio.h>
- # include <math.h>
- # include <ctype.h>
- # include "fbm.h"
-
- typedef struct rasterfile {
- long ras_magic;
- long ras_width;
- long ras_height;
- long ras_depth;
- long ras_length;
- long ras_type;
- long ras_maptype;
- long ras_maplength;
- } RASHDR;
-
- # define RT_STANDARD 1
- # define RMT_NONE 0
- # define RMT_EQUAL_RGB 1
- # define RMT_RAW 2
-
- # define RED 0
- # define GRN 1
- # define BLU 2
-
- /****************************************************************
- * write_sun (image, wfile)
- ****************************************************************/
-
- #ifndef lint
- static char *fbmid =
- "$FBM flsun.c <1.0> 25-Jun-90 (C) 1989,1990 by Michael Mauldin, source \
- code available free from MLM@CS.CMU.EDU and from UUNET archives$";
- #endif
-
- write_sun (image, wfile)
- FBM *image;
- FILE *wfile;
- { RASHDR rhdr;
- register int i, j, byte;
- register unsigned char *bmp, *rp, *gp, *bp;
- int width, height, plnlen, clrlen, rowlen, depth, bits;
-
- if (image->hdr.planes != 1 && image->hdr.planes != 3)
- { fprintf (stderr,
- "Error, write_sun can only handle images with depth 1 or 3\n");
- return (0);
- }
-
- if (image->hdr.physbits != 8)
- { fprintf (stderr,
- "Error, write_sun can only handle 8 physical bits per pixel\n");
- return (0);
- }
-
- /* This restriction should be fixed */
- if (image->hdr.bits == 1 && (image->hdr.rowlen % 16) != 0)
- { fprintf (stderr,
- "Error, 1 bit deep files must have rowlen (%d) divisible by 16");
- return (0);
- }
-
- /* Allow for input rowlen to be greater than output rowlen */
- if (image->hdr.bits == 1)
- { bits = 1; }
- else
- { bits = 8; }
-
- # ifdef DEBUG
- fprintf (stderr,
- "write_sun: [%dx%d] rowlen %d, planes %d, bits %d, physbits %d, using %d\n",
- image->hdr.cols,
- image->hdr.rows,
- image->hdr.rowlen,
- image->hdr.planes,
- image->hdr.bits,
- image->hdr.physbits,
- bits);
- # endif
-
- width = image->hdr.cols;
- height = image->hdr.rows;
- rowlen = image->hdr.rowlen;
- plnlen = image->hdr.plnlen;
- clrlen = image->hdr.clrlen;
- depth = bits * image->hdr.planes;
-
- /* Initialize Sun raster header */
- rhdr.ras_magic = SUN_MAGIC;
- rhdr.ras_width = width;
- rhdr.ras_height = height;
- rhdr.ras_depth = depth;
- rhdr.ras_length = plnlen * bits / 8;
- rhdr.ras_type = RT_STANDARD;
- rhdr.ras_maptype = depth > 8 ? RMT_RAW : clrlen ? RMT_EQUAL_RGB : RMT_NONE;
- rhdr.ras_maplength = clrlen;
-
- /* Write rasterfile header - note: use Sun byte order */
- put_long (rhdr.ras_magic, wfile, BIG);
- put_long (rhdr.ras_width, wfile, BIG);
- put_long (rhdr.ras_height, wfile, BIG);
- put_long (rhdr.ras_depth, wfile, BIG);
- put_long (rhdr.ras_length, wfile, BIG);
- put_long (rhdr.ras_type, wfile, BIG);
- put_long (rhdr.ras_maptype, wfile, BIG);
- put_long (rhdr.ras_maplength, wfile, BIG);
-
- /* Dump colormap if need be */
- if (clrlen > 0)
- { fwrite (image->cm, 1, clrlen, wfile); }
-
- /* Write bytes */
- switch (depth)
- { case 24: rp = &image->bm[0];
- gp = rp + plnlen;
- bp = gp + plnlen;
-
- for (i=0; i<plnlen; i++)
- { fputc (*rp++, wfile);
- fputc (*gp++, wfile);
- fputc (*bp++, wfile);
- }
- break;
-
- case 8: fwrite (image->bm, 1, plnlen, wfile);
- break;
-
- case 1:
- # ifdef DEBUG
- fprintf (stderr, "Writing Sun 1bit file [%dx%d] rowlen %d\n",
- width, height, rowlen);
- # endif
- for (j=0; j<height; j++)
- { bmp = &(image->bm[j*rowlen]);
- byte = 0;
-
- for (i=0; i<rowlen; i++)
- { byte = (byte << 1) | (*bmp++ ? 0 : 1);
-
- if ((i & 7) == 7)
- { fputc (byte, wfile); byte = 0; }
- }
- }
- break;
-
- default: fprintf (stderr,
- "Error, write_sun given invalid depth %d bits\n",
- depth);
- return (0);
- }
- return (1);
- }
-
- /****************************************************************
- * read_sun (image, rfile)
- ****************************************************************/
-
- read_sun (image, rfile, mstr, mlen)
- FBM *image;
- FILE *rfile;
- char *mstr;
- int mlen;
- { RASHDR rhdr;
- int width, height, plnlen, rowlen, clrlen, res, depth;
- register int i, j, byte;
- register unsigned char *bmp, *rp, *gp, *bp;
- int m1, m2, m3, m4;
-
- m1 = NEXTMCH(rfile,mstr,mlen) & 0xff;
- m2 = NEXTMCH(rfile,mstr,mlen) & 0xff;
- m3 = NEXTMCH(rfile,mstr,mlen) & 0xff;
- m4 = NEXTMCH(rfile,mstr,mlen) & 0xff;
-
- rhdr.ras_magic = (m1 << 24) | (m2 << 16) | (m3 << 8)| (m4);
-
- /* Write rasterfile header - note: use Sun byte order */
- if (rhdr.ras_magic != SUN_MAGIC)
- { fprintf (stderr, "Error, not a Sun raster file (bad magic %08x)\n",
- rhdr.ras_magic);
- return (0);
- }
-
- rhdr.ras_width = get_long (rfile, BIG);
- rhdr.ras_height = get_long (rfile, BIG);
- rhdr.ras_depth = get_long (rfile, BIG);
- rhdr.ras_length = get_long (rfile, BIG);
- rhdr.ras_type = get_long (rfile, BIG);
- rhdr.ras_maptype = get_long (rfile, BIG);
- rhdr.ras_maplength = get_long (rfile, BIG);
-
- /* Check for nonstandard rasterfile formats */
- if (rhdr.ras_type != RT_STANDARD)
- { fprintf (stderr, "Error: rasterfile is not a Sun RT_STANDARD file\n");
- return (0);
- }
-
- if (rhdr.ras_maplength > 0 && rhdr.ras_maptype != RMT_EQUAL_RGB)
- { fprintf (stderr, "Error: color rasterfile is not RMT_EQUAL_RGB\n");
- return (0);
- }
-
- if (rhdr.ras_maplength == 0 &&
- rhdr.ras_maptype != RMT_NONE &&
- rhdr.ras_maptype != RMT_RAW)
- { fprintf (stderr, "Error: black and white rasterfile is not RMT_NONE\n");
- return (0);
- }
-
- if (rhdr.ras_depth != 24 && rhdr.ras_depth != 8 && rhdr.ras_depth != 1)
- { fprintf (stderr, "Error, bits per pixel (%d) must be 1, 8 or 24\n",
- rhdr.ras_depth);
- return (0);
- }
-
- /* Initialize and allocate input image */
- width = rhdr.ras_width;
- height = rhdr.ras_height;
- depth = rhdr.ras_depth;
- clrlen = rhdr.ras_maplength;
-
- if (depth == 1)
- { rowlen = 16 * ((width + 15) / 16);
- plnlen = rowlen * height;
- }
- else
- { rowlen = width;
- if (rowlen & 1) rowlen++;
-
- plnlen = rowlen * height; /* Corrected 4-6-90 Gary W. Sherwin */
- }
-
- # ifdef DEBUG
- fprintf (stderr, "Reading Sun raster, [%dx%d], rowlen %d, depth %d, clrlen %d\n",
- width, height, rowlen, depth, clrlen );
- # endif
-
- /* Check for consitency between colormap and depth */
- if (depth > 8 && clrlen > 0)
- { fprintf (stderr,
- "Error, input has colormap of length %d, but %d bits per pixel\n",
- clrlen, depth);
- return (0);
- }
-
- /* Initialize image header */
- image->hdr.cols = width;
- image->hdr.rows = height;
- image->hdr.planes = (depth == 24) ? 3 : 1;
- image->hdr.bits = (depth == 24) ? 8 : depth;
- image->hdr.physbits = 8;
- image->hdr.rowlen = rowlen;
- image->hdr.plnlen = plnlen;
- image->hdr.clrlen = clrlen;
- image->hdr.aspect = 1.0;
- image->hdr.title[0] = '\0';
- image->hdr.credits[0] = '\0';
-
- /* Allocate space */
- alloc_fbm (image);
-
- /* Read colormap if need be */
- if (clrlen > 0 && (res = fread (image->cm, 1, clrlen, rfile)) != clrlen)
- { fprintf (stderr, "Error: couldn't read colormap, read %d of %d bytes\n",
- res, clrlen);
- return (0);
- }
-
- /* Read bytes */
- switch (depth)
- { case 24: rp = &image->bm[0];
- gp = rp + plnlen;
- bp = gp + plnlen;
-
- for (i=0; i<plnlen && !feof (rfile); i++)
- { *rp++ = fgetc (rfile);
- *gp++ = fgetc (rfile);
- *bp++ = fgetc (rfile);
- }
-
- if (i<plnlen)
- { fprintf (stderr, "Error: %s %d of %d pixels (%d bytes)\n",
- "EOF on bitmap after",
- i, plnlen, plnlen * image->hdr.planes);
- return (0);
- }
-
- break;
-
- case 8: if ((res = fread (image->bm, 1, plnlen, rfile)) != plnlen)
- { fprintf (stderr,
- "Error: EOF on bitmap after %d of %d bytes\n",
- res, plnlen);
- return (0);
- }
- break;
-
- case 1: for (j=0; j<height; j++)
- { bmp = &(image->bm[j * rowlen]);
-
- for (i=0; i<rowlen; i++)
- { if ((i&7) == 0)
- { if ((byte = fgetc (rfile)) == EOF)
- { fprintf (stderr,
- "Error: EOF on bitmap after %d of %d bytes\n",
- j*rowlen + i, height*rowlen);
- return (0);
- }
- }
-
- *bmp++ = (byte & 0x80) ? BLACK : WHITE;
- byte <<= 1;
- }
- }
- break;
- default: fprintf (stderr, "Invalid depth %d bits\n", depth);
- return (0);
- }
-
- return (1);
- }
-